<?php
/*

	Plugin Name: &Uuml;ber Dashboard
	Description: A unified dashboard for multiple WordPress installations, allowing you to remotely monitor the version of WordPress and the versions of your plugins.
	Version:     0.1
	Plugin URI:  http://code.google.com/p/unifieddashboard/
	Author:      The WordHackers at WordCamp UK 2009

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

*/

class UberDashboardConsumer {

	function UberDashboardConsumer() {

		add_action( 'wp_dashboard_setup', array( &$this, 'add_widget' ) );
		add_action( 'admin_init',         array( &$this, 'register_setting' ) );
		add_action( 'admin_menu',         array( &$this, 'admin_menus' ) );
		add_action( 'scheduled_action',    array( &$this, 'query_producers' ) );
		
		// register activation & deactivation hooks
		register_activation_hook(__FILE__, array( &$this, 'my_activation' ) );
		register_deactivation_hook(__FILE__, array( &$this, 'my_deactivation' ) );

	}
	
	function my_activation() {
		
		wp_schedule_event(time(), 'twicedaily', 'scheduled_action');
		
	}
	
	function my_deactivation() {
	
		wp_clear_scheduled_hook('scheduled_action');
		
	}
	
	function query_producers() {
	
		/*
			This function is scheduled to run twice daily. It needs to query
			the producers and store the results locally.
		*/

	}

	function register_setting() {

		register_setting( 'uber_dashboard', 'uber_dashboard', array( &$this, 'sanitize' ) );

	}

	function sanitize( $option ) {

		foreach ( $option['sites'] as $key => $site ) {
			if ( isset( $_POST['uber_dashboard']['sites'][$key]['delete'] ) )
				unset ( $option['sites'][$key] );
		}

		return $option;

	}

	function admin_menus() {

		add_options_page(
			'&Uuml;ber Dashboard',
			'&Uuml;ber Dashboard',
			'manage_options',
			'uber_dashboard',
			array( &$this, 'settings' )
		);

	}

	function settings() {

		$options = get_option( 'uber_dashboard', array() );

		?>
		<div class="wrap">

		<div class="icon32" id="icon-options-general"><br/></div>
		<h2>&Uuml;ber Dashboard</h2>

		<?php if ( !empty( $options['sites'] ) ) { ?>

			<form action="options.php" method="POST">
			<?php settings_fields( 'uber_dashboard' ); ?>

			<table class="widefat" cellspacing="0">

			<thead>
				<tr>
					<th scope="col">WordPress address (URL)</th>
					<th scope="col">Username</th>
					<th scope="col">Password</th>
					<th scope="col" width="80">Delete?</th>
				</tr>
			</thead>
			<tbody>

			<?php foreach ( (array) $options['sites'] as $key => $site ) { ?>

				<tr>
					<td><input name="uber_dashboard[sites][<?php echo $key; ?>][siteurl]" type="text" value="<?php echo $site['siteurl']; ?>" size="40" class="regular-text code" /></td>
					<td><input name="uber_dashboard[sites][<?php echo $key; ?>][username]" type="text" value="<?php echo $site['username']; ?>" size="20" class="regular-text" /></td>
					<td><input name="uber_dashboard[sites][<?php echo $key; ?>][password]" type="password" value="<?php echo $site['password']; ?>" size="20" class="regular-text" /></td>
					<td><input type="checkbox" name="uber_dashboard[sites][<?php echo $key; ?>][delete]" value="1" /></td>
				</tr>

			<?php } ?>

			</tbody>
			</table>

			<p class="submit"><input type="submit" class="button-primary" value="Update &raquo;" /></p>

			</form>

		<?php } ?>

		<h3>Add a site to show on this site&rsquo;s dashboard</h3>

		<form action="options.php" method="POST">
		<?php settings_fields( 'uber_dashboard' ); ?>
		<?php $name = 'uber_dashboard[sites][' . (count( $options['sites'] )+1) . ']'; ?>
		<?php if ( !empty( $options['sites'] ) ) { foreach ( (array) $options['sites'] as $key => $site ) { ?>
		<input type="hidden" name="uber_dashboard[sites][<?php echo $key; ?>][siteurl]" value="<?php echo $site['siteurl']; ?>" />
		<input type="hidden" name="uber_dashboard[sites][<?php echo $key; ?>][username]" value="<?php echo $site['username']; ?>" />
		<input type="hidden" name="uber_dashboard[sites][<?php echo $key; ?>][password]" value="<?php echo $site['password']; ?>" />
		<?php } } ?>

		<table class="form-table">

			<tbody>

				<tr class="form-field form-required">
					<th scope="row"><label for="new_siteurl">WordPress address (URL)</label></th>
					<td><input id="new_siteurl" name="<?php echo $name; ?>[siteurl]" type="text" value="" size="40" class="regular-text code" /><br />
					<span class="description">This should <strong>exactly</strong> match the &rsquo;WordPress address&lsquo; setting on the &rsquo;Settings&lsquo; screen.</span></td>
				</tr>
				<tr class="form-field form-required">
					<th scope="row"><label for="new_username">Username</label></th>
					<td><input id="new_username" name="<?php echo $name; ?>[username]" type="text" value="" size="20" class="regular-text" /><br />
					<span class="description">Any valid username for the blog...</span></td>
				</tr>
				<tr class="form-field form-required">
					<th scope="row"><label for="new_password">Password</label></th>
					<td><input id="new_password" name="<?php echo $name; ?>[password]" type="password" value="" size="20" class="regular-text" /><br />
					<span class="description">...and that user&rsquo;s password.</span></td>
				</tr>

			</tbody>

		</table>

		<p class="submit"><input type="submit" class="button-primary" value="Add &raquo;" /></p>

		</form>

		<?php

	}

	function add_widget() {

		wp_add_dashboard_widget( 'UberDashboardWidget', '&Uuml;ber Dashboard', array( &$this, 'widget' ) );	

	} 

	function widget() {

		$options = get_option( 'uber_dashboard' );

		if ( empty( $options['sites'] ) ) {
			echo 'Please add a site on the <a href="options-general.php?page=uber_dashboard">&Uuml;ber Dashboard Settings Screen</a>.';
			return;
		}

		foreach ( (array) $options['sites'] as $key => $site ) {

			$options = $this->get_options( $site['siteurl'] . '/xmlrpc.php', $site['username'], $site['password'] );
			$plugins = $this->get_plugins( $site['siteurl'] . '/xmlrpc.php', $site['username'], $site['password'] );

			if ( !is_array( $options ) ) {
				echo '<p>Could not get a response from ' . $site['siteurl'] . '. Is XML-RPC enabled?';
				continue;
			}

			$title   = $options['blog_title']['value'];
			$version = $options['software_version']['value'];

			echo '<h4 style="margin-bottom:15px">' . wptexturize( $title ) . '</h4>';

			if ( $version ) {

				$status = wordpress_api_version_check( $version );

				if ( $status->response == 'latest' )
					echo "<p><strong>WordPress</strong> is $version (up to date)"; // current message
				else
					echo "<p><strong>WordPress</strong> is $version (out of date), current is {$status->current}"; //stale message

			} else {

				echo '<p>Could not get WordPress version from ' . $title . '.';

			}

			if ( is_array( $plugins ) ) {

				echo '<ul style="padding-bottom:5px;border-bottom:1px solid #ccc">';

				#rofl( $plugins );

				foreach ( $plugins as $plugin ) {
					echo '<li><strong>' . $plugin['Name'] . '</strong> is version ' . $plugin['Version'] . '</li>';
				}
				echo '</ul>';

			} else {

				echo '<p>Could not get plugin list from ' . $title . '. Is the &Uuml;ber Dashboard plugin installed and activated?';

			}

		}

	}

	function get_plugins( $url, $username = null, $password = null ) {

		require_once( ABSPATH . WPINC . '/class-IXR.php' );

		$client = new IXR_Client( $url );

		if ( $client->query( 'wcuk.getPlugins', $username, $password ) )
			return $client->getResponse();
		else
			return $query;

	}

	function get_options( $url, $username = null, $password = null ) {

		require_once( ABSPATH . WPINC . '/class-IXR.php' );

		$client = new IXR_Client( $url );

		if ( $client->query( 'wp.getOptions', 0, $username, $password ) )
			return $client->getResponse();
		else
			return $query;

	}

}

class UberDashboardProducer {

	function UberDashboardProducer() {

		add_filter( 'xmlrpc_methods', array( &$this, 'add_methods' ) );

	}

	function add_methods( $methods ) {

		$methods['wcuk.getPlugins'] = array( &$this, 'get_plugins' );

		return $methods;

	}

	function get_plugins( $args ) {

		$username = $args[0];
		$password = $args[1];

		if ( !get_option( 'enable_xmlrpc' ) ) {
			return false;
		}

		$user = wp_authenticate( $username, $password );

		if ( is_wp_error( $user ) ) {
			return false;
		}

		return get_plugins();

	}

}

function wordpress_api_version_check( $version ) {

	$response = wp_remote_get( 'http://api.wordpress.org/core/version-check/1.3/?version=' . $version );

	if ( is_wp_error( $response ) ) {
		return false;
	}

	if ( 200 != $response['response']['code'] ) {
		return false;
	}

	$body = trim( $response['body'] );
	$body = str_replace( array( "\r\n", "\r" ), "\n", $body );

	foreach ( explode( "\n\n", $body ) as $entry ) {

		$lines = explode( "\n", $entry );
		$status = new stdClass();
		$status->response = esc_attr( $lines[0] );

		if ( isset( $lines[1] ) )
			$status->url = esc_url( $lines[1] );
		if ( isset( $lines[2] ) )
			$status->package = esc_url( $lines[2] );
		if ( isset( $lines[3] ) )
			$status->current = esc_attr( $lines[3] );
		if ( isset( $lines[4] ) )
			$status->locale = esc_attr( $lines[4] );

	}

	return $status;

}

$uberdashboardconsumer = new UberDashboardConsumer();
$uberdashboardproducer = new UberDashboardProducer();

?>